import type { TableColumnProps, ProSaasTableExposeType } from '~/components/ProSaasTable/typings'
import type {
  SystemRoleDataItemType,
  SystemRoleStateType,
  SpermissionsSetStateType
} from './typings'
import { defineComponent, reactive, ref, onMounted } from 'vue'
import { useStore } from 'vuex'
import {
  ElCard,
  ElFormItem,
  ElSelect,
  ElOption,
  ElInput,
  ElButton,
  ElLink,
  ElIcon,
  ElMessage,
  ElMessageBox,
  ElDialog,
  ElTabs,
  ElTabPane,
  ElTree
} from 'element-plus'
import {
  View,
  EditPen,
  Delete,
  Plus,
  Setting,
  CircleClose,
  CircleCheck
} from '@element-plus/icons-vue'
import type { tenantSelectEnum } from '~/store/system/typings'
import { handleTrim } from '~/utils/util'
import { cloneDeep } from 'lodash'
import ProSaasTable from '~/components/ProSaasTable'
import SearchForm from '~/components/ProForm/SearchForm'
import useVuexGetters from '~/hooks/useVuexGetters'
import SystemRoleOptionsModal from './options'

export default defineComponent(function systemRole() {
  const store = useStore()
  const proSaasTableRef = ref<ProSaasTableExposeType>()
  const treeMenusRef = ref() // 权限设置 菜单树
  const treeDatasRef = ref() // 权限设置 数据树
  const formValues = reactive<SystemRoleDataItemType>({})
  const state = reactive<SystemRoleStateType>({
    modalVisible: false,
    type: 'read',
    record: {}
  })
  const spermissionsSetState = reactive<SpermissionsSetStateType>({
    activeName: 'first', // 默认为"菜单权限"
    permissionsSetVisible: false,
    treeMenus: [],
    treeDatas: [],
    treeProps: {
      // value: 'id',
      label: 'title',
      children: 'children'
    },
    treeMenusCheckedKeys: [],
    treeDatasCheckedKeys: []
  })

  const userState = useVuexGetters('user', ['permission'])
  const systemPostState = useVuexGetters('systemPost', ['tenantSelectList', 'tenantSelectEnum'])
  // const systemRoleState = useVuexGetters('systemRole', ['userRoleEnum']) // 上级角色 // 暂隐藏

  onMounted(async () => {
    store.dispatch('systemPost/GetTenantSelect') // 所属租户
  })

  // 操作列、表头 弹窗
  const handleChangeOptionsModal = (
    type: SystemRoleStateType['type'],
    record?: SystemRoleDataItemType
  ) => {
    state.modalVisible = !state.modalVisible
    state.record = record || {}
    state.type = type
    if (!state.modalVisible) {
      proSaasTableRef.value!?.toSearch() // 更新主列表
    }
    // if (state.modalVisible) {
    //   store.dispatch('systemRole/GetUserRoleSelectList', { tenantId: record?.tenantId }) // 上级角色 // 暂隐藏
    // }
  }

  // 删除
  const handleOpenDeleteConfirm = (record?: SystemRoleDataItemType) => {
    let params = ''
    if (record?.id) {
      params = record?.id
    }
    ElMessageBox.confirm('确定将选择数据删除?', {
      buttonSize: 'small',
      type: 'warning',
      closeOnClickModal: false, // 点遮罩层不关弹窗
      draggable: true // 可拖拽
    })
      .then(async () => {
        await store.dispatch('systemRole/PostUserRoleRemove', params).then((res) => {
          if (res?.code === 200) {
            proSaasTableRef.value!?.toSearch()
            ElMessage({ type: 'success', message: '操作成功' })
          } else {
            ElMessage({ type: 'error', message: res?.msg ?? '操作失败' })
          }
        })
      })
      .catch(() => {})
  }

  // 权限设置
  const permissionsSet = async () => {
    if (proSaasTableRef.value!.selecteds?.length !== 1) {
      ElMessage({ type: 'warning', message: '请仅选择一条数据' })
      return
    }
    // 折叠全部节点
    setTimeout(() => {
      for (const i in treeMenusRef.value.store._getAllNodes()) {
        treeMenusRef.value.store._getAllNodes()[i].expanded = false
      }
    }, 100)

    spermissionsSetState.permissionsSetVisible = !spermissionsSetState.permissionsSetVisible
    if (spermissionsSetState.permissionsSetVisible) {
      // 获取已选中的
      let params = ''
      const element = cloneDeep(proSaasTableRef.value?.selecteds)
      const idsArr = element.map((item: { id: string }) => item.id) // 存待处理的行id
      params = idsArr.join(',')

      const res = await store.dispatch('systemRole/GetUserRoleTreeKeys', { roleIds: params })
      if (res?.code === 200) {
        spermissionsSetState.treeMenusCheckedKeys = res.data.menu // 取值
        spermissionsSetState.treeDatasCheckedKeys = res.data.dataScope
        permissionsSetContentsAjax()
      }
    } else {
      spermissionsSetState.treeMenusCheckedKeys = [] // 置空已选的(关闭)
      spermissionsSetState.treeDatasCheckedKeys = [] // 置空已选的(关闭)
    }
  }

  // 权限设置 主内容
  const permissionsSetContentsAjax = async () => {
    const res = await store.dispatch('systemRole/GetUserRoleGrantTreeAdmin')
    spermissionsSetState.treeMenus = res.data.menu
    spermissionsSetState.treeDatas = res.data.dataScope
  }

  // 提交权限设置
  const permissionsSetSubmit = async () => {
    const element = cloneDeep(proSaasTableRef.value?.selecteds)
    const idsArr = element.map((item: { id: string }) => item.id) // 行id

    spermissionsSetState.menusRowId = treeMenusRef.value
      .getCheckedKeys()
      .concat(treeMenusRef.value.getHalfCheckedKeys())
    //  树展示key
    spermissionsSetState.menusRowIds = treeMenusRef.value.getCheckedKeys()

    spermissionsSetState.datasRowId = treeDatasRef.value
      .getCheckedKeys()
      .concat(treeDatasRef.value.getHalfCheckedKeys())
    const params = {
      dataScopeIds: spermissionsSetState.datasRowId,
      menuIds: spermissionsSetState.menusRowId,
      roleIds: idsArr
    }
    const res = await store.dispatch('systemRole/PostUserRoleGrant', params)
    if (res?.code === 200) {
      ElMessage({ type: 'success', message: '操作成功' })
      store.dispatch('user/GetButtons') // 更新按钮权限
      permissionsSet() // 关闭
    } else {
      ElMessage({ type: 'error', message: res?.msg ?? '操作失败' })
    }
  }

  // 按回车搜索列表
  const handleKeyDownEnterSubmitForm = (evt: Event | KeyboardEvent) => {
    if ((evt as KeyboardEvent).key === 'Enter') proSaasTableRef.value!?.toSearch()
  }

  // 清空搜索
  const searchTable = () => {
    setTimeout(() => {
      proSaasTableRef.value!?.toSearch()
    }, 100)
  }

  const columns: TableColumnProps<SystemRoleDataItemType>[] = [
    {
      label: '角色名称',
      prop: 'roleName',
      minWidth: 180,
      showOverflowTooltip: true,
      align: 'center'
    },
    {
      label: '所属租户',
      prop: 'tenantId',
      minWidth: 180,
      enumValues: systemPostState.tenantSelectEnum,
      showOverflowTooltip: true,
      align: 'center'
    },
    /* {
      label: '角色别名',
      prop: 'roleAlias',
      minWidth: 180,
      showOverflowTooltip: true,
      align: 'center'
    }, */
    // { // 暂隐藏
    //   label: '上级角色',
    //   prop: 'parentId',
    //   minWidth: 180,
    //   enumValues: systemRoleState.userRoleEnum,
    //   showOverflowTooltip: true,
    //   align: 'center'
    // },
    {
      label: '角色排序',
      prop: 'sort',
      minWidth: 180,
      showOverflowTooltip: true,
      align: 'center'
    },
    {
      label: '操作',
      prop: 'options',
      fixed: 'right',
      unFixed: true,
      minWidth: 180,
      width: 260,
      align: 'center',
      render: ({ row }) => {
        return (
          <>
            {userState.permission.value.has('system_role_view') && (
              <ElLink type="primary" onClick={() => handleChangeOptionsModal('read', row)}>
                <ElIcon>
                  <View />
                </ElIcon>
                &nbsp;查看
              </ElLink>
            )}
            &nbsp;&nbsp;&nbsp;
            {userState.permission.value.has('system_role_update') && (
              <ElLink type="primary" onClick={() => handleChangeOptionsModal('update', row)}>
                <ElIcon>
                  <EditPen />
                </ElIcon>
                &nbsp;编辑
              </ElLink>
            )}
            &nbsp;&nbsp;&nbsp;
            {userState.permission.value.has('system_role_remove') && (
              <ElLink type="primary" onClick={() => handleOpenDeleteConfirm(row)}>
                <ElIcon>
                  <Delete />
                </ElIcon>
                &nbsp;删除
              </ElLink>
            )}
          </>
        )
      }
    }
  ]

  return () => {
    const treeMenusCheckedKeys = cloneDeep(spermissionsSetState.treeMenusCheckedKeys)
    const treeDatasCheckedKeys = cloneDeep(spermissionsSetState.treeDatasCheckedKeys)

    // 防止什么都不改时报错
    spermissionsSetState.menusRowId = treeMenusCheckedKeys // 传的id们
    spermissionsSetState.datasRowId = treeDatasCheckedKeys // 传的id们

    return (
      <ElCard>
        <SearchForm
          searchFormProps={{
            model: formValues
          }}
          searchformResponsiveCol={[
            <ElFormItem key="roleName" prop="roleName" label="角色名称：">
              <ElInput
                v-model={formValues.roleName}
                placeholder="请输入 角色名称"
                clearable
                onKeydown={handleKeyDownEnterSubmitForm}
                onClear={searchTable}
              />
            </ElFormItem>,
            <ElFormItem key="tenantId" prop="tenantId" label="所属租户：">
              <ElSelect
                v-model={formValues.tenantId}
                placeholder="请选择或输入关键字"
                filterable
                clearable
                onChange={searchTable}
              >
                {systemPostState.tenantSelectList?.value?.map((item: tenantSelectEnum) => (
                  <ElOption key={item?.tenantId} label={item?.tenantName} value={item?.tenantId} />
                ))}
              </ElSelect>
            </ElFormItem>,
            <ElFormItem key="roleAlias" prop="roleAlias" label="角色别名：">
              <ElInput
                v-model={formValues.roleAlias}
                placeholder="请输入 角色别名"
                clearable
                onKeydown={handleKeyDownEnterSubmitForm}
                onClear={searchTable}
              />
            </ElFormItem>
          ]}
          handleSearchList={proSaasTableRef.value?.toSearch}
        />
        <ProSaasTable<SystemRoleDataItemType>
          ref={proSaasTableRef}
          columns={columns}
          rowKey="id"
          lazy
          // treeProps={{ children: 'children', hasChildren: 'hasChildren' }}
          hasIndex
          hasSelection
          searchParams={{
            roleName: formValues.roleName && handleTrim(formValues.roleName), // 角色名称
            roleAlias: formValues.roleAlias && handleTrim(formValues.roleAlias) // 角色别名
          }}
          searchFormProps={{
            model: formValues
          }}
          dispatchType="systemRole/GetUserRoleList"
          // dispatchTypeGetListKeys="data"
          headerTitle={
            <>
              {userState.permission.value.has('system_role_add') && (
                <ElButton type="primary" onClick={() => handleChangeOptionsModal('add')}>
                  <ElIcon>
                    <Plus />
                  </ElIcon>
                  &nbsp; 新增
                </ElButton>
              )}
              {userState.permission.value.has('system_role_permission') && (
                <ElButton type="danger" plain onClick={() => permissionsSet()}>
                  <ElIcon>
                    <Setting />
                  </ElIcon>
                  &nbsp; 权限设置
                </ElButton>
              )}
            </>
          }
        />
        {state.modalVisible && (
          <SystemRoleOptionsModal
            visible={state.modalVisible}
            type={state.type}
            record={state.record}
            onCancel={() => handleChangeOptionsModal('read')}
          />
        )}

        <ElDialog // 权限设置
          width={'20%'}
          title="角色配置"
          closeOnClickModal={false} // 点遮罩层不关弹窗
          draggable // 可拖拽
          modelValue={spermissionsSetState.permissionsSetVisible}
          beforeClose={() => permissionsSet()}
          v-slots={{
            footer: () => (
              <>
                <ElButton onClick={() => permissionsSet()}>
                  <ElIcon>
                    <CircleClose />
                  </ElIcon>
                  取消
                </ElButton>
                <ElButton type="primary" onClick={() => permissionsSetSubmit()}>
                  <ElIcon>
                    <CircleCheck />
                  </ElIcon>
                  确定
                </ElButton>
              </>
            )
          }}
        >
          <ElTabs v-model={spermissionsSetState.activeName} type="border-card">
            <ElTabPane label="菜单权限" name="first">
              <ElTree
                ref={treeMenusRef}
                data={spermissionsSetState.treeMenus}
                props={spermissionsSetState.treeProps}
                showCheckbox
                nodeKey="id"
                defaultCheckedKeys={treeMenusCheckedKeys}
              ></ElTree>
            </ElTabPane>
            <ElTabPane label="数据权限" name="second">
              <ElTree
                ref={treeDatasRef}
                data={spermissionsSetState.treeDatas}
                props={spermissionsSetState.treeProps}
                showCheckbox
                nodeKey="id"
                defaultCheckedKeys={treeDatasCheckedKeys}
              ></ElTree>
            </ElTabPane>
          </ElTabs>
        </ElDialog>
      </ElCard>
    )
  }
})
